<template>
  <div class="video-uploader">
    <el-upload
        :accept="accept"
        :action="uploadUrl"
        :before-upload="beforeUpload"
        :headers="computedHeaders"
        :isView="isView"
        :on-error="handleError"
        :on-progress="handleProgress"
        :on-success="handleSuccess"
        :show-file-list="false"
        class="upload-area"
    >
      <el-button :disabled="isView" type="primary">上传视频</el-button>
      <span v-if="uploading" style="margin-left: 10px;">上传中：{{ uploadPercent }}%</span>
    </el-upload>

    <div v-if="videoUrl" class="preview-container">
      <h4>视频预览：</h4>
      <div class="video-wrapper">
        <video ref="videoPlayer" :src="videoUrl" controls></video>
        <el-button
            v-if="videoUrl"
            :disabled="isView"
            class="delete-btn"
            icon="Delete"
            size="small"
            type="danger"
            @click="removeVideo"
        />
      </div>
    </div>
  </div>
</template>

<script setup>
import {computed, onBeforeUnmount, ref, watch} from 'vue'
import {getToken} from "@/utils/auth"
import {ElMessage} from 'element-plus'

const props = defineProps({
  modelValue: String,
  maxSize: {
    type: Number,
    default: 100 * 1024 * 1024 // 100MB
  },
  headers: {
    type: Object,
    default: () => ({})
  },
  accept: {
    type: String,
    default: "video/*"
  },
  disabled: Boolean,
  isView: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['update:modelValue'])

const videoUrl = ref(props.modelValue || "")
const uploading = ref(false)
const uploadPercent = ref(0)
const videoPlayer = ref(null)
const uploadUrl = import.meta.env.VITE_APP_BASE_API + "/common/upload"

const computedHeaders = computed(() => ({
  Authorization: "Bearer " + getToken(),
  ...props.headers
}))

watch(() => props.modelValue, (newVal) => {
  videoUrl.value = newVal || ""
})

const beforeUpload = (file) => {
  const isVideo = file.type.startsWith("video/")
  const isLtMax = file.size <= props.maxSize

  if (!isVideo) {
    ElMessage.error("只能上传视频文件！")
    return false
  }

  if (!isLtMax) {
    ElMessage.error(`视频大小不能超过 ${props.maxSize / (1024 * 1024)}MB！`)
    return false
  }

  return true
}

const handleProgress = (event) => {
  uploading.value = true
  uploadPercent.value = Math.floor(event.percent)
}

const handleSuccess = (response) => {
  uploading.value = false
  uploadPercent.value = 0
  const fullUrl = response.url
  videoUrl.value = fullUrl
  emit('update:modelValue', fullUrl)
  ElMessage.success("上传成功！")
}

const handleError = () => {
  uploading.value = false
  uploadPercent.value = 0
  ElMessage.error("上传失败，请重试！")
}

const removeVideo = () => {
  // 停止正在播放的视频
  if (videoPlayer.value) {
    videoPlayer.value.pause()
    videoPlayer.value.removeAttribute('src')
    videoPlayer.value.load()
  }

  videoUrl.value = ""
  emit('update:modelValue', "")
}

onBeforeUnmount(() => {
  removeVideo()
})

// 暴露停止视频的方法
const stopVideo = () => {
  if (videoPlayer.value) {
    videoPlayer.value.pause()
    videoPlayer.value.currentTime = 0
  }
}

// 暴露方法给父组件
defineExpose({
  stopVideo
})
</script>

<style scoped>
.video-uploader {
  max-width: 600px;
}

.preview-container {
  margin-top: 20px;
  position: relative;
}

.video-wrapper {
  position: relative;
  width: 100%;
  max-height: 400px;
  background-color: #000;
}

.video-wrapper video {
  width: 100%;
  height: auto;
  max-height: 400px;
  display: block;
}

.delete-btn {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 10;
}
</style>
